package com.smh.demo1.a32;

import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
import org.springframework.web.servlet.resource.CachingResourceResolver;
import org.springframework.web.servlet.resource.EncodedResourceResolver;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;

/**
 * @author shiminghui
 * @date 2025/5/4 15:05
 * @description: TODO
 */
@Configuration
public class WebConfig {


    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        return new TomcatServletWebServerFactory();
    }

    @Bean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }

    @Bean
    public DispatcherServletRegistrationBean dispatcherServletRegistrationBean() {
        DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet(), "/");
        registrationBean.setLoadOnStartup(1);
        return registrationBean;
    }


    @Bean
    // 静态资源映射
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping(ApplicationContext context) {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();

        // 获取所有ResourceHttpRequestHandler
        Map<String, ResourceHttpRequestHandler> beansOfType = context.getBeansOfType(ResourceHttpRequestHandler.class);

        simpleUrlHandlerMapping.setUrlMap(beansOfType);
        return simpleUrlHandlerMapping;
    }

    @Bean
    public HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
        return new HttpRequestHandlerAdapter();
    }


    @Bean("/**") //通配符
    public ResourceHttpRequestHandler r1() {
        ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
        requestHandler.setLocations(List.of(new ClassPathResource("static/")));
        // 优化静态资源映射
        requestHandler.setResourceResolvers(List.of(
                new CachingResourceResolver(new ConcurrentMapCacheManager(), "cache1"), //用来缓存的
                new EncodedResourceResolver(), // 用来读取压缩文件
                new PathResourceResolver()// 默认就这一个
        ));
        return requestHandler;
    }

    @Bean("/template/**")
    public ResourceHttpRequestHandler r2() {
        ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
        requestHandler.setLocations(List.of(new ClassPathResource("templates/")));
        return requestHandler;
    }


    @PostConstruct
    public void init() throws IOException {
        // 读取静态资源
        ClassPathResource classPathResource = new ClassPathResource("static/");

        File file = classPathResource.getFile();
        List<File> files = Arrays.stream(file.listFiles()).filter(file1 -> file1.getName().endsWith(".html")).collect(Collectors.toList());
        System.out.println(files);
        files.forEach(file1 -> {
            System.out.println(file1.getAbsolutePath() + ".gz");
            // 读取文件内容
            try (FileInputStream fis = new FileInputStream(file1); GZIPOutputStream gos = new GZIPOutputStream(new FileOutputStream(file1.getAbsolutePath() + ".gz"))) {
                byte[] bytes = new byte[1024];
                int len;
                while ((len = fis.read(bytes)) != -1) {
                    gos.write(bytes, 0, len);
                }
                gos.finish();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

}
